package me.isaac.learn_scala

import java.awt.Font

import me.isaac.learn_scala.ch06.{Account, DoNothingAction, Stock}

import scala.collection.JavaConversions.{mapAsJavaMap, mapAsScalaMap}
import scala.collection.mutable.ArrayBuffer
import scala.beans.BeanProperty

object Main {

	def main(args: Array[String]): Unit = {
		c06()
	}

	def c03(): Unit = {
		//定长数组
		val nums = new Array[Int](10) //val nums = Array[Int]()
		val a = Array("a", "b")
		val b = new Array[String](5)
		b(0) = "11"

		//变长数组
		val c = ArrayBuffer[Int]() //等同于val c = new ArrayBuffer[Int]
		c += 1 //在尾端添加元素
		c += (1, 2, 3, 5) //在尾端添加多个元素
		c ++= Array(7, 8, 9) //在尾端追加集合
		c.trimEnd(2) //移除尾部5个元素
		c.insert(2, 7) //在下标2之前插入
		c.insert(2, 8, 9) //在下标2之前插入任意多元素
		println(c)
		c.remove(2) //移除下标2
		println(c)
		c.remove(2, 2) //移除下标2开始的2个元素
		println(c)

		val d = c.toArray //从ArrayBuffer转换为Array
		val e = d.toBuffer //从Array转换为ArrayBuffer

		//遍历数组和数组缓冲
		val arr_1 = Array(2, 3, 4, 5, 6)
		println("遍历数组")
		for (i <- 0 until arr_1.length) println(s"$i:${arr_1(i)}")
		println("两个元素一跳")
		for (i <- 0 until arr_1.length by 2) println(s"$i:${arr_1(i)}")
		println("i<-arr_1.indices")
		for (i <- arr_1.indices) println(s"$i:${arr_1(i)}")
		println("i<-arr_1.indices.reverse")
		for (i <- arr_1.indices.reverse) println(s"$i:${arr_1(i)}")
		println("i<-arr_1.indices by 2")
		for (i <- arr_1.indices by 2) println(s"$i:${arr_1(i)}")

		//数组转换
		//for推导式
		val arr_2 = Array(1, 2, 3, 5, 7, 11, 13, 17, 19)
		val result = for (elem <- arr_2) yield 2 * elem //将arr_2中所有元素乘2
		println(result.mkString(","))
		val result_1 = for (elem <- arr_2 if elem > 10) yield elem //找出arr_2中大于10的元素
		println(result_1.mkString(","))

		//常用算法
		println(Array(1, 3, 5, 7, 9).sum) //求和
		println(Array(1, 3, 5, 7, 9).max) //最大值
		println(ArrayBuffer(3, 7, 5, 9, 1).sorted) //排序
		println(ArrayBuffer(3, 7, 5, 9, 1).sortWith(_ > _)) //使用sortWith进行排序
		val arr_3 = Array(17, 13, 3, 5, 11)
		scala.util.Sorting.quickSort(arr_3) //可以直接对一个数组进行排序，但不能对数组缓冲进行排序
		println(arr_3.toBuffer)

		//多维数组
		val matrix = Array.ofDim[Double](3, 4) //3行4列的二维数组
		val triangle = new Array[Array[Double]](5)
		for (i <- triangle.indices) triangle(i) = new Array[Double](i + 1) //创建一个不规则数组

		//与Java的互操作
		//Scala不允许自动将String[]数组转换为Object[]数组
		val arr_4 = Array("A", "B", "C")
		val index = java.util.Arrays.binarySearch(arr_4.asInstanceOf[Array[Object]], "C")
	}

	def c04(): Unit = {
		/*第4章*/
		//构造映射
		val scores = Map("Alice" -> 10, "Bob" -> 3, "Cindy" -> 8) //构造一个不可变的Map[String,Int]，值不能被改变
		val scores_1 = scala.collection.mutable.Map("Alice" -> 10, "Bob" -> 3, "Cindy" -> 8) //可变映射
		val scores_2 = scala.collection.mutable.Map[String, Int]() //构建空映射必须给定类型参数
		val scores_3 = Map(("Alice", 10), ("Bob", 3), ("Cindy", 8))

		//获取映射中的值
		val bobScore = scores("Bob") //查询"Bob"键对应的值，如果映射不包含该键则抛出异常
		val contain = scores.contains("David") //集合中不存在"David"键
		val bobScore1 = if (scores.contains("Bob")) scores("Bob") else 0
		val bobScore2 = scores.getOrElse("Bob", 0) //上面语句的快捷写法

		//更新映射中的值
		println(scores_1)
		scores_1("Bob") = 9 //修改键"Bob"对应的值
		scores_1("David") = 6 //新建一个KV对到scores_1
		println(scores_1)
		scores_1 += ("Bob" -> 2, "David" -> 1, "Lucy" -> 4) //使用+=添加多个关系
		println(scores_1)
		scores_1 -= "Bob" //使用-=移除KV对
		println(scores_1)
		val newScore = scores + ("Bob" -> 6, "Jane" -> 5) //构建一个新的不可变Map
		println(newScore)
		var newScore1 = scores + ("Bob" -> 6, "Jane" -> 5)
		newScore1 -= "Bob" //可以从不可变Map中移除元素

		//迭代映射
		println("迭代映射 for ((k, v) <- scores) println(f\"$k:$v\")")
		for ((k, v) <- scores) println(f"$k:$v")
		println("迭代映射 for (k <- scores.keys) println(f\"$k:${scores(k)}\")")
		for (k <- scores.keys) println(f"$k:${scores(k)}")
		println("迭代映射 for (k <- scores.keySet) println(f\"$k:${scores(k)}\")")
		for (k <- scores.keySet) println(f"$k:${scores(k)}")
		println("迭代映射 for(v<-scores.values) println(v)")
		for (v <- scores.values) println(v)

		//与Java的互操作
		val scores_4: scala.collection.mutable.Map[String, Int] = new java.util.TreeMap[String, Int] //将Java Map转换为Scala Map
		val attrs = Map((java.awt.font.TextAttribute.FAMILY, "Serif"), (java.awt.font.TextAttribute.SIZE, 10))
		val font = new Font(attrs) //将Scala Map转换为Java Map

		//元组
		val t = (1, 3.14, "Fred")
		println(t._2) //元组各组成部件从1开始
		val (first, second, third) = t //使用模式钵为获取元组元素
		val (first1, second1, _) = t //不需要第3个元素
		println("New York".partition(_.isUpper)) //函数需要返回不止一个值的情况

		//拉链操作
		val symbol = Array("<", "-", ">")
		val counts = Array(2, 10, 2)
		val pairs = symbol.zip(counts)
		for ((k, v) <- pairs) print(k * v)
	}

	def c05(): Unit = {
		//简单类和无参方法
		val myCounter = new Counter
		myCounter.increment()
		println(myCounter.current())

		//带getter和setter的属性
		val fred = new Person
		println(fred.age)
		fred.age = 10
		println(fred.age)
		val jerry = new Person1
		println(jerry.age())
		jerry.age_=(15)
		println(jerry.age())

		//只带getter的属性

		//对象私有字段 见Counter1类

		//Bean属性 见Counter2类

		//辅助构造器 见Person2类

		//主构造器
		var jane = new Person3("Jane", 15)
		println(jane.description)
		println(jane.name)

		var tony = new Person4("Tony", 13)
		println(tony.description)
		//不能使用println(tony.age)

		//嵌套类
		val chatter = new Network
		val myFace = new Network
		val galen = chatter.join("Galen")
		val raj = chatter.join("Raj")
		galen.contacts += raj
		val sheldon = myFace.join("Sheldon")
		// galen.contacts += sheldon 会报错 found:myFace.Member required:chatter.Member
	}

	def c06(): Unit = {
		//单例对象
		println(MyAccount.newUniqueNumber())
		println(MyAccount.newUniqueNumber())

		//伴生对象
		val account = new Account
		println(account.id)

		//扩展类或物质的对象
		DoNothingAction.undo()
		DoNothingAction.redo()

		//apply方法
		val stock1 = Stock("000001", "万科A")
		val stock2 = new Stock("600001", "深发展A", 4.1)

		//应用程序对象
		//见 ../ch06/Hello

		//枚举
		for (light <- TrafficLightColor.values) println(s"${light.id}:$light")
	}
}

class Counter {
	private var value = 100

	def increment(): Unit = {
		value += 1
	}

	def current(): Int = value
}

class Person {
	var age = 40
}

//重新定义getter和setter方法
class Person1 {
	private var myAge = 0

	def age(): Int = myAge

	def age_=(newValue: Int): Unit = {
		if (newValue > myAge) myAge = newValue
	}
}

class Counter1 {
	private[this] var value = 100

	def increment(): Unit = {
		value += 1
	}

	def current(): Int = value

	//无法使用 def isLess(other: Counter1): Boolean = value < other.value
}

class Counter2 {
	@BeanProperty var name: String = _
}

class Person2 {
	private var name = ""
	private var age = 0

	//辅助构造器的名称是this
	//辅助构造器必须以一个对先前已定义的其他辅助构造器或主构造器的调用开始
	def this(name: String) {
		this()
		this.name = name
	}

	def this(name: String, age: Int) {
		this(name)
		this.age = age
	}
}

class Person3(val name: String, val age: Int) {
	println("Just constructed another person")

	def description: String = s"$name is $age years old."
}

class Person4(name: String, private var age: Int) {
	println("Just constructed another person")

	def description: String = s"$name is $age years old."
}

class Person5 private(val id: Int) {
	//主构造器私有

}

class Network {

	class Member(val name: String) {
		val contacts = new ArrayBuffer[Member]()
	}

	private val member = new ArrayBuffer[Member]()

	def join(name: String): Member = {
		val m = new Member(name)
		member += m
		m
	}
}

object MyAccount {
	private var lastNumber = 0

	def newUniqueNumber(): Long = {
		lastNumber += 1
		lastNumber
	}
}

object TrafficLightColor extends Enumeration {
	val Red = Value(11, "red")
	val Green = Value("green")
	val Yellow = Value(15, "yellow")
}